﻿/****************************************************************************************************
	Copyright (C) 2010 RapidWebDev Organization (http://rapidwebdev.org)
	Author: Eunge, Legal Name: Jian Liu, Email: eunge.liu@RapidWebDev.org

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using BaoJianSoft.ExtensionModel.Properties;
using BaoJianSoft.Common;

namespace BaoJianSoft.ExtensionModel.Statistic
{
	/// <summary>
	/// The filter algorithm to filter and analyze data by checking whether the data is between MinValue and MaxValue configured.
	/// The "between" algorithm only works for Decimal/DateTime/Integer typed value.
	/// </summary>
	public partial class BetweenStatisticFilter
	{
		/// <summary>
		/// Does the value match the algorithm.
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		public override bool IsMatch(object value)
		{
			try
			{
				switch (this.PropertyType)
				{
					case PropertyTypes.DateTime:
						if (value == null || !(value is DateTime)) return false;
						return this.CompareDateTimeValue((DateTime)value);

					case PropertyTypes.Decimal:
						if (value == null || !(value is decimal)) return false;
						return this.CompareDecimalValue((decimal)value);

					case PropertyTypes.Integer:
						if (value == null || !(value is int)) return false;
						return this.CompareIntegerValue((int)value);
				}
			}
			catch
			{
				return false;
			}

			throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "The filter \"Between\" cannot be used for property type \"{0}\".", this.PropertyType));
		}

		/// <summary>
		/// Convert the instance to string.
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			if (!string.IsNullOrEmpty(this.MaxValue) && !string.IsNullOrEmpty(this.MinValue))
			{
				string betweenString = string.Format(CultureInfo.InvariantCulture, Resources.BetweenFormat, this.MinValue, this.MaxValue);
				return string.Format(CultureInfo.InvariantCulture, "{0} {1}", this.PropertyLabel, betweenString);
			}
			else if (!string.IsNullOrEmpty(this.MaxValue) && string.IsNullOrEmpty(this.MinValue))
				return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", this.PropertyLabel, Resources.LessThan, this.MaxValue);
			else if (string.IsNullOrEmpty(this.MaxValue) && !string.IsNullOrEmpty(this.MinValue))
				return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", this.PropertyLabel, Resources.MoreThan, this.MinValue);

			return string.Format(CultureInfo.InvariantCulture, "{0} {1}", this.PropertyLabel, Resources.NoLimitation);
		}

		private bool CompareDateTimeValue(DateTime value)
		{
			DateTime maxValue = DateTime.MaxValue, minValue = DateTime.MinValue;
			try
			{
				if (!string.IsNullOrEmpty(this.MaxValue))
					maxValue = (DateTime)Kit.ConvertType(this.MaxValue, typeof(DateTime));
			}
			catch
			{
			}

			try
			{
				if (!string.IsNullOrEmpty(this.MinValue))
					minValue = (DateTime)Kit.ConvertType(this.MinValue, typeof(DateTime));
			}
			catch
			{
			}

			return value >= minValue && value <= maxValue;
		}

		private bool CompareIntegerValue(int value)
		{
			int maxValue = int.MaxValue, minValue = int.MinValue;
			try
			{
				if (!string.IsNullOrEmpty(this.MaxValue))
					maxValue = (int)Kit.ConvertType(this.MaxValue, typeof(int));
			}
			catch
			{
			}

			try
			{
				if (!string.IsNullOrEmpty(this.MinValue))
					minValue = (int)Kit.ConvertType(this.MinValue, typeof(int));
			}
			catch
			{
			}

			return value >= minValue && value <= maxValue;
		}

		private bool CompareDecimalValue(decimal value)
		{
			decimal maxValue = decimal.MaxValue, minValue = decimal.MinValue;
			try
			{
				if (!string.IsNullOrEmpty(this.MaxValue))
					maxValue = (decimal)Kit.ConvertType(this.MaxValue, typeof(decimal));
			}
			catch
			{
			}

			try
			{
				if (!string.IsNullOrEmpty(this.MinValue))
					minValue = (decimal)Kit.ConvertType(this.MinValue, typeof(decimal));
			}
			catch
			{
			}

			return value >= minValue && value <= maxValue;
		}
	}
}
